﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Microsoft.Ccr.Core;
using NUnit.Framework;
using XcoAppSpaces.Contracts.CcrExtensions;
using XcoAppSpaces.Core.CcrWiring;
using XcoAppSpaces.Core;
using XcoAppSpaces.Core.CcrWiring.CcrRemote;
using XcoAppSpaces.Contracts.Messaging;

namespace test.XcoAppSpaces.Core.CcrWiring
{
	[TestFixture]
	public class testAnonymousRemotableTask
	{
		[Test]
		public void TestPostSequential()
		{
			int receivedCount = 0;
			var port = new Port<int>();
			var task = new AnonymousRemotableTask((msg => { Assert.AreEqual(receivedCount, msg.Data.Msg);
			                                              	receivedCount++; }), 
															"testaddr", "testservice", Guid.NewGuid(), port, MessageTransferMode.Sequential);
			var dpq = new DispatcherQueue("test");
			Arbiter.Activate(dpq, new Receiver(false, port, task));
			
			int postCount = 10;
			for (int i = 0; i < postCount; i++)
				port.Post(i);
			Thread.Sleep(200);

			Assert.AreEqual(postCount, receivedCount);
		}

		[Test]
		public void TestPostSequential2()
		{
			int receivedCount = 0;
			var port = new Port<int>();
			var task = new AnonymousRemotableTask((msg =>
			{
				Assert.AreEqual(receivedCount, msg.Data.Msg);
				receivedCount++;
			}),
															"testaddr", "testservice", Guid.NewGuid(), port, MessageTransferMode.Sequential);
			var dpq = new DispatcherQueue("test");
			port.ReceiveWithRemotableTask(dpq, task);

			int postCount = 10;
			for (int i = 0; i < postCount; i++)
				port.Post(i);
			Thread.Sleep(200);

			Assert.AreEqual(postCount, receivedCount);
		}

		[Test]
		public void TestPostParallel()
		{
			int receivedCount = 0;
			var port = new Port<int>();
			var task = new AnonymousRemotableTask((msg => { receivedCount++; Console.WriteLine(msg.Data); }), "testaddr", "testservice", Guid.NewGuid(), port, MessageTransferMode.Parallel);
			var dpq = new DispatcherQueue("test");
			Arbiter.Activate(dpq, new Receiver(true, port, task));
			
			int postCount = 10;
			for (int i = 0; i < postCount; i++)
				port.Post(i);
			Thread.Sleep(200);

			Assert.AreEqual(postCount, receivedCount);
		}

		[Test]
		public void TestPost_TaskStillAvailable()
		{
			var port = new Port<int>();
			var task = new AnonymousRemotableTask((msg =>
			                                       	{
			                                       		Console.WriteLine("posted");
			                                       		Thread.Sleep(100);
			                                       	}),
			                                      "testaddr", "testservice", Guid.NewGuid(), port, MessageTransferMode.Sequential);
			var dpq = new DispatcherQueue("test");
			port.ReceiveWithRemotableTask(dpq, task);

			port.Post(1);
			var taskFromPort = port.GetRemotableTask();

			Assert.IsNotNull(taskFromPort);
		}
	}
}
